package com.wyix;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 同步与异步编程对比案例 - 电子商务订单处理系统
 * 展示同步处理与异步处理的区别、线程池应用、并发控制和任务调度
 */
public class SyncAsyncOrderProcessing {
    // 订单计数器（线程安全）
    private static final AtomicInteger ORDER_COUNTER = new AtomicInteger(0);
    // 库存数据（线程安全的ConcurrentHashMap）
    private static final Map<String, Integer> INVENTORY = new ConcurrentHashMap<>();
    // 格式化日期时间
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm:ss.SSS");
    // 异步任务线程池（核心3线程，最大5线程，队列20，自定义线程名）
    private static final ExecutorService ASYNC_EXECUTOR = new ThreadPoolExecutor(
            3, 5, 60L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(20),
            new ThreadFactory() {
                private final AtomicInteger threadNumber = new AtomicInteger(1);

                @Override
                public Thread newThread(Runnable r) {
                    return new Thread(r, "async-worker-" + threadNumber.getAndIncrement());
                }
            }
    );

    // 订单实体类
    static class Order {
        String orderId;
        String userId;
        List<OrderItem> items;
        long createTime;

        public Order(String userId, List<OrderItem> items) {
            this.orderId = "ORDER_" + ORDER_COUNTER.getAndIncrement();
            this.userId = userId;
            this.items = items;
            this.createTime = System.currentTimeMillis();
        }
    }

    // 订单商品项实体类
    static class OrderItem {
        String productId;
        int quantity;
        double price;

        public OrderItem(String productId, int quantity, double price) {
            this.productId = productId;
            this.quantity = quantity;
            this.price = price;
        }
    }

    // 订单处理结果类
    static class OrderResult {
        String orderId;
        boolean success;
        String message;
        long processTime;

        public OrderResult(String orderId, boolean success, String message, long processTime) {
            this.orderId = orderId;
            this.success = success;
            this.message = message;
            this.processTime = processTime;
        }

        @Override
        public String toString() {
            return "{success=" + success + ", message='" + message + '\'' + ", 耗时=" + processTime + "ms}";
        }
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        System.out.println("===== 电子商务订单处理系统启动 =====");
        initInventory(); // 初始化库存

        // 创建测试订单（含2个商品）
        Order order = createNewOrder(
                "user_001",
                Arrays.asList(
                        new OrderItem("iPhone 13", 1, 5999.0),
                        new OrderItem("AirPods Pro", 1, 1599.0)
                )
        );

        // 同步处理订单（必须立即完成的核心流程）
        System.out.println("\n===== 开始同步处理订单 =====");
        long syncStart = System.currentTimeMillis();
        OrderResult syncResult = processOrderSync(order);
        long syncTime = System.currentTimeMillis() - syncStart;
        System.out.printf("===== 同步处理完成，耗时: %dms，结果: %s =====\n", syncTime, syncResult);

        // 异步处理订单（非核心流程，如物流通知、用户通知）
        System.out.println("\n===== 开始异步处理订单附加任务 =====");
        long asyncStart = System.currentTimeMillis();
        Future<OrderResult> asyncFuture = processOrderAsync(order);

        // 主线程可执行其他操作（模拟）
        System.out.println("主线程：异步任务已提交，开始处理其他操作...");
        Thread.sleep(300); // 模拟主线程处理其他任务

        // 获取异步结果（阻塞等待）
        OrderResult asyncResult = asyncFuture.get();
        long asyncTime = System.currentTimeMillis() - asyncStart;
        System.out.printf("===== 异步处理完成，耗时: %dms，结果: %s =====\n", asyncTime, asyncResult);

        // 关闭线程池
        ASYNC_EXECUTOR.shutdown();
    }

    // 初始化库存
    private static void initInventory() {
        INVENTORY.put("iPhone 13", 10);
        INVENTORY.put("AirPods Pro", 20);
        INVENTORY.put("VIVO Pro", 40);
        INVENTORY.put("HUA Pro", 100);
        INVENTORY.put("XIAOMI Pro", 390);
        System.out.println("初始化库存：" + INVENTORY);
    }

    // 创建新订单
    private static Order createNewOrder(String userId, List<OrderItem> items) {
        Order order = new Order(userId, items);
        System.out.printf("[%s] 创建新订单：%s（用户：%s，商品数：%d）\n",
                DATE_FORMAT.format(order.createTime), order.orderId, userId, items.size());
        return order;
    }

    // 同步处理订单（核心流程：库存扣减+支付）
    private static OrderResult processOrderSync(Order order) {
        long startTime = System.currentTimeMillis();
        try {
            // 1. 验证并扣减库存（线程安全操作）
            boolean stockValid = checkAndDeductStock(order.items);
            if (!stockValid) {
                return new OrderResult(order.orderId, false, "库存不足", System.currentTimeMillis() - startTime);
            }

            // 2. 模拟支付（耗时500ms）
            Thread.sleep(500);
            System.out.printf("[%s] 订单%s 支付完成\n", DATE_FORMAT.format(System.currentTimeMillis()), order.orderId);

            return new OrderResult(order.orderId, true, "订单处理成功", System.currentTimeMillis() - startTime);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return new OrderResult(order.orderId, false, "处理中断", System.currentTimeMillis() - startTime);
        }
    }

    // 异步处理订单（附加流程：物流通知+用户短信）
    private static Future<OrderResult> processOrderAsync(Order order) {
        return ASYNC_EXECUTOR.submit(() -> {
            long startTime = System.currentTimeMillis();
            try {
                // 1. 模拟物流系统对接（耗时800ms）
                Thread.sleep(800);
                System.out.printf("[%s] 订单%s 已通知物流系统\n", DATE_FORMAT.format(System.currentTimeMillis()), order.orderId);

                // 2. 模拟用户短信通知（耗时300ms）
                Thread.sleep(300);
                System.out.printf("[%s] 订单%s 用户短信通知完成\n", DATE_FORMAT.format(System.currentTimeMillis()), order.orderId);

                return new OrderResult(order.orderId, true, "异步任务完成", System.currentTimeMillis() - startTime);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return new OrderResult(order.orderId, false, "异步任务中断", System.currentTimeMillis() - startTime);
            }
        });
    }

    // 线程安全的库存检查与扣减
    private static boolean checkAndDeductStock(List<OrderItem> items) {
        // 先检查所有商品库存是否足够
        for (OrderItem item : items) {
            if (INVENTORY.getOrDefault(item.productId, 0) < item.quantity) {
                System.out.printf("库存不足：商品%s 剩余%d，需要%d\n",
                        item.productId, INVENTORY.get(item.productId), item.quantity);
                return false;
            }
        }

        // 扣减库存（使用putIfAbsent保证原子性）
        for (OrderItem item : items) {
            INVENTORY.compute(item.productId, (k, v) -> v - item.quantity);
        }
        System.out.println("扣减后库存：" + INVENTORY);
        return true;
    }
}